package microservice

import (
	"bytes"
	"fmt"
	"hxy/repo/config"
	"hxy/repo/model"
	"path"
	"text/template"
)

type GenCodeRequest struct {
	Gitid   uint   `json:"gitid"`
	Gencode string `json:"gencode"`
	GenMode uint   `json:"genmode"`
}

// #region PV and PVC template
const PVC_template = `apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: {{ .PVCName }}
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: nfs
  resources:
    requests:
      storage: {{ .PVCSize }}
`
const PV_template = `apiVersion: v1
kind: PersistentVolume
metadata:
  name: {{ .PVName }}
spec:
  capacity:
    storage: {{ .PVSize }}
  accessModes:
    - ReadWriteOnce
  storageClassName: {{ .StorageType }}
  hostPath:
    path: /data
    persistentVolumeReclaimPolicy: Recycle
    storageClassName: nfs
    nfs:
      path: /nfsroot/pv-1g-21
      server: master
`

//#endregion

// #region DeploymentServiceforModule Template
const DeploymentServiceforModule = `
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{.Name}}
spec:
  replicas: {{.Replicas}}
  selector:
    matchLabels:
      app: {{.Name}}
  replicas: 1
  template:
    metadata:
      labels:
        app: {{.Name}}
    spec:
      containers:
        - name: {{.Name}}
          image: {{.Image}}
          imagePullPolicy: Always
          ports:
            - containerPort: {{.Port}}
          resources:
            requests:
              cpu: 50m
              memory: 160Mi
            limits:
              cpu: 200m
              memory: 500Mi
          readinessProbe:
            tcpSocket:
              port: 15680
            initialDelaySeconds: 160
            periodSeconds: 10
            timeoutSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: {{.Name}}
spec:
  selector:
    app: {{.Name}}
  ports:
    - name: http
      port: {{.Port}}
      targetPort: {{.Port}}
  type: LoadBalancer
`

// #endregion

// #region database pv\pvc\data_deplotment\service
const dataMongoTemplate = `
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: {{.Name}}-pvc
spec:
  accessModes: [ "ReadWriteMany" ]
  storageClassName: nfs
  resources:
    requests:
      storage: 1Gi
---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{.Name}}
spec:
  selector:
    matchLabels:
      app: {{.Name}}
  replicas: 1
  template:
    metadata:
      labels:
        app: {{.Name}}
    spec:
      containers:
      - name: {{.Name}}
        image: mongo
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 27017
        resources:
          requests:
            cpu: 150m
            memory: 200Mi
        volumeMounts:
          - name: mongo-persistent-storage
            mountPath: /data/db
      volumes:
        - name: mongo-persistent-storage
          persistentVolumeClaim:
            claimName: {{.Name}}-pvc

---
apiVersion: v1
kind: Service
metadata:
  name: {{.Name}}
spec:
  ports:
    - port: 27017
  selector:
   app: {{.Name}}
`

// #endregion

type deployserviceValues struct {
	ProjectName string
	Replicas    int
	Image       string
	Name        string
	Port        int
}

func generateTemplate(values deployserviceValues) (string, error) {
	// 定义 Kubernetes YAML 文件的模板

	// 创建一个模板对象
	tmplObj, err := template.New("k8s-template").Parse(DeploymentServiceforModule)
	if err != nil {
		return "", err
	}

	// 将 values 对象传递给模板，并渲染模板
	var result bytes.Buffer
	err = tmplObj.Execute(&result, values)
	if err != nil {
		return "", err
	}

	// 返回渲染后的模板字符串
	return result.String(), nil
}

func TestTemplate() {
	// 创建一个 deployserviceValues 对象，并设置一些值
	values := deployserviceValues{
		Replicas: 3,
		Image:    "nginx",
		Name:     "my-nginx",
		Port:     80,
	}

	// 生成 Kubernetes YAML 文件的字符串
	yamlString, err := generateTemplate(values)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	// 输出 Kubernetes YAML 文件的字符串
	fmt.Println(yamlString)
}

type PVPVCValues struct {
	PVCName     string
	PVCSize     string
	PVName      string
	PVSize      string
	StorageType string
}

// 生成 PersistentVolumeClaim（PVC）的模板代码
func GeneratePVC(values PVPVCValues) (string, error) {
	tmpl, err := template.New("pvc").Parse(PVC_template)
	if err != nil {
		return "", err
	}

	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, values); err != nil {
		return "", err
	}

	return buf.String(), nil
}

func GenerateMongoDataTemplate(service string) (string, error) {
	tmpl, err := template.New("mongo-temp").Parse(dataMongoTemplate)
	if err != nil {
		return "", err
	}

	var buf bytes.Buffer
	datatemp := struct {
		Name string
	}{
		service,
	}
	if err := tmpl.Execute(&buf, datatemp); err != nil {
		return "", err
	}
	return buf.String(), nil

}

// 生成 PersistentVolume（PV）的模板代码
func GeneratePV(values PVPVCValues) (string, error) {
	tmpl, err := template.New("pv").Parse(PV_template)
	if err != nil {
		return "", err
	}

	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, values); err != nil {
		return "", err
	}

	return buf.String(), nil
}

/*
genmode: 0
采用二进制位标识
b0000
b10 数据库
b01 deployment
b11 数据库 & deployment
*/
func GenYamlByGitModle(git model.GitModel, genmode uint) string {
	code_gen := ""
	submodules := ready2dockerbuildModule(git.ID)
	for index, _module := range submodules {
		var template deployserviceValues
		Yaml, _ := parseSubmodule(path.Join(git.Path, _module.Name))
		template.Image = path.Join(config.DockerRegistryAddr, git.Name, _module.Name)
		template.Name = _module.Name
		template.Port = int(Yaml.Serve.Port)
		template.ProjectName = git.Name
		template.Replicas = 1
		var template_gen string
		var err error
		if (genmode & 0b01) > 0 {
			template_gen, err = generateTemplate(template)
			if err != nil {
				continue
			}
			code_gen += template_gen
		}

		if (genmode & 0b10) > 0 {
			code_gen += "\r\n---\r\n"
			template_gen, err = GenerateMongoDataTemplate(_module.Name)
			if err != nil {
				continue
			}
			code_gen += template_gen
		}

		if index != len(submodules)-1 {
			code_gen += "\r\n---\r\n"
		}
	}
	return code_gen
}
